package com.gw.yunke.web;

import com.gw.yunke.constant.GlobalConstant;
import com.gw.yunke.domain.*;
import com.gw.yunke.domain.dto.CourseModifyReq;
import com.gw.yunke.domain.dto.CourseQueryReq;
import com.gw.yunke.domain.dto.CourseQueryResp;
import com.gw.yunke.domain.dto.CourseRankReq;
import com.gw.yunke.domain.dto.PartReq;
import com.gw.yunke.domain.dto.ResultData;
import com.gw.yunke.domain.dto.SectionResp;
import com.gw.yunke.service.*;
import com.gw.yunke.service.impl.MultipartFileService;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import org.apache.log4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.*;
import java.text.ParseException;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import static com.gw.yunke.domain.dto.ResultData.OK;
import static com.gw.yunke.utils.MiscUtils.*;

/**
 * 用于处理创建 课程、章节、小节的请求
 */

@RestController
@RequestMapping(value = "/yunke/course")
public class CourseController {

  @Autowired
  private ICourseService courseService;
  @Autowired
  private IUserService userService;
  @Autowired
  private ISectionService sectionService;
  @Autowired
  private IPartService partService;
  @Autowired
  private IVideoService videoService;
  @Autowired
  private MultipartFileService multipartFileService;
  @Autowired
  private IPartVideoService partVideoService;
  @Autowired
  private IImageService imageService;
  @Autowired
  private GlobalConstant globalConstant;

  private static final org.slf4j.Logger log = LoggerFactory.getLogger(CourseController.class);

  @ApiOperation(value = "获取课程列表", notes = "根据查询条件(包括分页情况)获取符合条件的课程", response = ResultData.class)
  @ApiImplicitParam(name = "courseQueryReq", value = "String id;\n" +
          "    String name;\n" +
          "    String createrId;\n" +
          "    String createrName;\n" +
          "    Date beginTime;\n" +
          "    Date endTime;\n" +
          "    Integer pageNum;//用于分页\n" +
          "    Integer pageSize;", paramType = "JSON")
  @RequestMapping(value = "/getCourseList", method = RequestMethod.POST)
  public ResultData getCourseList(@RequestBody(required = false) CourseQueryReq courseQueryReq,@CookieValue(required = false,value = "sso")String token) throws Exception {

    if (courseQueryReq == null) {
      courseQueryReq = new CourseQueryReq();
    }
    if (isNull(courseQueryReq.getPageNum())) {
      courseQueryReq.setPageNum(1);

    }
    if (isNull(courseQueryReq.getPageSize())) {
      courseQueryReq.setPageSize(20);
    }

    if(!StringUtils.isEmpty(token)){
      User user = new User();
      userService.checkLogin(token,user);
      if(user != null){
        courseQueryReq.setUserId(user.getId());
      }
    }
    ResultData<List<CourseQueryResp>> resultData = new ResultData<List<CourseQueryResp>>();
    List<CourseQueryResp> courseQueryRespList = courseService.getCourseByExample(courseQueryReq);
    resultData.setCode(OK);
    resultData.setData(courseQueryRespList);
    resultData.setMessage("查询成功");

    return resultData;

  }


  @ApiOperation(value = "创建课程", notes = "根据课程必要信息创建课程，需登录状态 携带cookie", consumes = "application/x-www-form-urlencoded", response = ResultData.class)
  @ApiImplicitParams({
          @ApiImplicitParam(name = "course_name", required = true, value = "course_name 课程名称"),
          @ApiImplicitParam(name = "description", required = false, value = "description 课程描述"),
          @ApiImplicitParam(name = "course_type", required = false, value = "course_type 课程标签"),

  })
  @RequestMapping(value = "/createCourse", method = RequestMethod.POST)
  public ResultData<Integer> createCourse(@RequestBody CourseModifyReq courseModifyReq,
                                         @RequestParam(value = "image", required = false) MultipartFile multipartFile,
                                         @CookieValue(value = "sso",required = false) String token) throws Exception {
    ResultData<Integer> resultData = new ResultData<>();

    User user = new User();
    userService.checkLogin(token,user);

    if(!user.getType()){
      throw new Exception("没有教师权限");
    }
    Course course = new Course();
    course.setName(courseModifyReq.getName());
    course.setCreateTime(new Date());
    course.setDescription(courseModifyReq.getDescription());
    course.setUpdateTime(new Date());
    course.setUserId(user.getId());
    course.setHint(courseModifyReq.getDirection());
    course.setInstitute(courseModifyReq.getCollege());
    course.setSpecialty(courseModifyReq.getMajor());
    if(courseModifyReq.getPublish()!=null && courseModifyReq.getPublish() > 0)
      course.setPublish(true);
    else
      //默认发布先
      course.setPublish(true);
    long now = System.currentTimeMillis();
    course.setCode((now%1000000)/100 +""+now%100000);
    if(multipartFile == null){
      //course.setImageId(globalConstant.defaultCourseImageId);
    }else{
      Long imageId  = multipartFileService.upLoadImage(multipartFile);
      if(imageId > 0){
        course.setImageId(imageId);
      }else{
        log.info("上传图片时出现问题 imageId:{} courseId:{}",imageId,course);
        course.setImageId(globalConstant.defaultCourseImageId);
      }
    }

    int result = courseService.createOrUpdateCourse(course);


    if (result > 0) {
      resultData.setCode(OK);
      resultData.setMessage("ok");
      resultData.setData(1);
    } else {
      resultData.setCode(ResultData.OK);
      resultData.setMessage("error");
      resultData.setData(-1);
    }

    return resultData;
  }


  @ApiOperation(value = "创建章节", notes = "根据必要信息创建课程章节，需登录状态 携带cookie", consumes = "application/x-www-form-urlencoded", response = ResultData.class)
  @ApiImplicitParams({
          @ApiImplicitParam(name = "course_id", required = true, value = "course_id 课程id", paramType = "formData"),
          @ApiImplicitParam(name = "description", required = false, value = "description 课程描述", paramType = "formData"),
          @ApiImplicitParam(name = "name", required = true, value = "name 章节名称", paramType = "formData"),

  })
  @RequestMapping(value = "/createSection", method = RequestMethod.POST)
  public ResultData<Long> createSection(@RequestBody Section sectionCreate,
                                          @CookieValue(value = "sso")String token) throws Exception {
    ResultData<Long> resultData = new ResultData<>();
    User user = new User();
    userService.checkLogin(token,user);
    if(!userService.checkCreatePermission(user,sectionCreate.getCourseId())){
      log.error("没有对当前课程操作的权限 courseId={},userId = {}",sectionCreate.getCourseId(),user.getId());
      throw new Exception("没有对当前课程操作的权限");
    }
    Section section = new Section();
    section.setCourseId(sectionCreate.getCourseId());
    section.setCreateTime(new Date());
    section.setName(sectionCreate.getName());
    if(sectionCreate.getDescription() != null)
      section.setDescription(sectionCreate.getDescription());
    if(sectionCreate.getSectionOrder() != null)
      section.setSectionOrder(sectionCreate.getSectionOrder());
    long result = sectionService.createOrUpdateSection(section);

    if (result > 0) {
      resultData.setCode(OK);
      resultData.setMessage("ok");
      resultData.setData(section.getId());
    } else {
      resultData.setCode(ResultData.ERROR);
      resultData.setData(-1L);
      resultData.setMessage("error in insert into section");
    }

    return resultData;
  }


  @ApiOperation(value = "获取章节信息", notes = "根据课程id获取对应的章节列表", consumes = "application/x-www-form-urlencoded", response = ResultData.class)
  @ApiImplicitParams({
          @ApiImplicitParam(name = "course_id", required = true, value = "course_id 课程id"),
  })
  @RequestMapping(value = "/sections", method = RequestMethod.POST)
  public ResultData getSections(@RequestBody Course course,@CookieValue(value = "sso",required = false)String token) throws Exception {
    User user = new User();
    userService.checkLogin(token,user);
    ResultData<List<SectionResp>> resultData = new ResultData<>();
    Long courseId = course.getId();
    resultData.setCode(OK);
    resultData.setData(sectionService.getSectionRespsByCourseId(courseId));
    resultData.setMessage("查询成功");

    return resultData;
  }

  @ApiOperation(value = "创建小节", notes = "根据必要信息创建课程下的小节，需登录状态 携带cookie", consumes = "application/x-www-form-urlencoded", response = ResultData.class)
  @ApiImplicitParams({
          @ApiImplicitParam(name = "section_id", required = true, value = "section_id 章节id"),
          @ApiImplicitParam(name = "name", required = true, value = "description 小节名称"),
          @ApiImplicitParam(name = "video", required = true, value = "上传视频"),

  })
  @RequestMapping(value = "/createPart", method = RequestMethod.POST)
  public ResultData createPart(@RequestBody PartReq partCreate,
                           @RequestParam(value = "video", required = false) MultipartFile multipartFile,
          @CookieValue("sso")String token) throws Exception {

    ResultData resultData = new ResultData();
    User user = new User();
    userService.checkLogin(token,user);

    if(!user.getType()){
      throw new Exception("没有教师权限");
    }

    int result = partService.createPart(partCreate,multipartFile,user);

    if(result > 0) {
      resultData.setCode(OK);
      resultData.setData(0);
    }else{
      resultData.setCode(OK);
      resultData.setData(-1);
      resultData.setMessage("上传过程出现问题");
    }
    return resultData;
  }



  @ApiOperation(value = "根据小节id获取视频流", notes = "需登录状态 携带cookie")
  @RequestMapping(value = "/video/{videoId}", method = RequestMethod.GET)
  public void getVideoStream(@PathVariable("videoId") Long videoId, HttpServletRequest request, HttpServletResponse response/*, @CookieValue("sso")String token*/) throws Exception {
    log.info("收到video请求");

    System.out.println("******************************");
    System.out.println(response.getHeaderNames());
    System.out.println("------------------------------");
    Enumeration enumeration = request.getHeaderNames();
    while(enumeration.hasMoreElements()){
      String s = (String) enumeration.nextElement();
      System.out.print(s+" : ");
      System.out.println(request.getHeader(s));
    }
    System.out.println("******************************");
    /*
    User user = userService.getUserInfoByToken("123");
    if (user == null) {
      throw new Exception("未登陆");
    }
    */
    //Long videoId = partVideoService.getVideoIdByPartId(partId);
    //response.setHeader();
    Video video = videoService.getVideoById(videoId);
    HttpHeaders httpHeaders = new HttpHeaders();
    response.setHeader("Content-Type","video/mp4");

    //httpHeaders.setContentType(new MediaType("audio/mp4"));
    //httpHeaders.setContentDispositionFormData("attachment",video.getLocalUrl());
    //return new ResponseEntity<byte[]>(FileCopyUtils.copyToByteArray(new File(video.getLocalUrl())),httpHeaders, HttpStatus.CREATED);

    File file = new File(video.getLocalUrl());
    //request.getHeader("Range");
    RandomAccessFile randomAccessFile = new RandomAccessFile(file,"r");
    //randomAccessFile.
    response.setHeader("Accept-Ranges","bytes");
    response.setHeader("connection","keep-alive");
    response.setHeader("Content-Range","bytes 0-"+(file.length()-1)+"/"+file.length());
    //response.setStatus(HttpStatus.PARTIAL_CONTENT.value());
    System.out.println("++++++++++++" + file.length() + " ------");
    response.setContentLength((int)file.length());
    InputStream in = null;
    OutputStream out = null;
    try {
      in = new FileInputStream(file);
      out = response.getOutputStream();
      byte[] buffer = new byte[1024 * 1024*4];
      int length;
      while ((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
      }
    } catch (IOException e) {
      log.error("文件错误");
      throw e;
    } finally {
      try {
        in.close();
        out.close();
      } catch (IOException e) {
        log.error("【文件流关闭异常】" + e.getMessage());
        throw e;
      }

    }


  }

  @RequestMapping(value = "/image/{imageId}", method = RequestMethod.GET)
  public void getImage(@PathVariable("imageId") Long imageId, HttpServletResponse response) throws Exception {
    log.info("收到image请求");
    Image image = imageService.getImageById(imageId);
    File file = new File(image.getLocalUrl());
    //RandomAccessFile randomAccessFile = new RandomAccessFile(image.getLocalUrl(),"r");
    InputStream in = null;
    OutputStream out = null;
    try {
      in = new FileInputStream(file);
      out = response.getOutputStream();
      byte[] buffer = new byte[1024*1024];
      int length;
      while ((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
      }
    } catch (IOException e) {
      log.error("文件错误");
      throw e;
    } finally {
      try {
        in.close();
        out.close();
      } catch (IOException e) {
        log.error("【文件流关闭异常】" + e.getMessage());
        throw e;
      }

    }
  }

  public void getCoursePPT() throws IOException {

    //OtherFile otherFile =
    /*
    File file = new File(pptFile.getLocalUrl());
    //RandomAccessFile randomAccessFile = new RandomAccessFile(image.getLocalUrl(),"r");
    InputStream in = null;
    OutputStream out = null;
    try {
      in = new FileInputStream(file);
      out = response.getOutputStream();
      byte[] buffer = new byte[1024*1024];
      int length;
      while ((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
      }
    } catch (IOException e) {
      log.error("文件错误");
      throw e;
    } finally {
      try {
        in.close();
        out.close();
      } catch (IOException e) {
        log.error("【文件流关闭异常】" + e.getMessage());
        throw e;
      }

    }
    */
  }

  @RequestMapping(value = "/video/info",method = RequestMethod.POST)
  public ResultData<Video> getVideoInfo(Long videoId){
    ResultData resultData = new ResultData();
    resultData.setCode(OK);
    resultData.setMessage("成功");
    resultData.setData(videoService.getVideoById(videoId));
    return resultData;
  }

  @RequestMapping(value = "/addRank",method = RequestMethod.POST)
  public ResultData rank(@RequestBody CourseRankReq courseRankReq,@CookieValue(value = "sso")String token) throws Exception {
    User user = userService.getUserInfoByToken(token);
    if (user == null) {
      throw new Exception("未获取到登录信息");
    }
    courseRankReq.setUserId(user.getId());
    int result = courseService.updateRank(courseRankReq);
    ResultData resultData = new ResultData();
    if(result > 0)
      resultData.setCode(OK);
    else
      resultData.setCode(ResultData.ERROR);

    return resultData;
  }


  public ResultData modifyCourse(@RequestBody CourseModifyReq courseModifyReq){

    if(courseModifyReq == null){
      return null;
    }
    courseService.modifyCourse(courseModifyReq);

    return null;
  }

  @RequestMapping(value = "/userCourse",method = RequestMethod.POST)
  public ResultData getUserCourses(@CookieValue(value = "sso",required = false)String token) throws Exception {
    User user = new User();
    userService.checkLogin(token,user);;
    List<CourseQueryResp> courseQueryRespList = courseService.getCourseByUserId(user.getId(),null);

    ResultData resultData = new ResultData();
    resultData.setCode(OK);
    resultData.setData(courseQueryRespList);

    return resultData;
  }



}
